﻿using System;
using System.Collections.Generic;
using System.Threading;
using CommonTypes.Server;
using Server.Model;

namespace Server.Services.Secondary
{
    public class SecondaryPingManager : PingManager
    {
        //This is executed on remoting threads
        public static ImAliveResponse processPing( String primaryId, long logicalClock, ServerData serverData )
        {
            if( primaryId.Equals( serverData.ServersInformation.PrimaryId ) )
            {
                serverData.PingInformation.PingReceived = true;

                if( !serverData.PerformingSync )
                {
                    lock( SecondaryMergingManager._secondaryLock )
                    {
                        if( logicalClock > serverData.ServerLogicalClock )
                            MergingManager.Synchronize( primaryId, serverData );
                        Monitor.Pulse( SecondaryMergingManager._secondaryLock );
                    }
                }

                return ImAliveResponse.OK;
            }
            else
                return ImAliveResponse.PRIMARY_UNKNOWN;
        }

        public override void executePingTimer( object args )
        {
            KeyValuePair<AutoResetEvent, ServerData> argPair = ( KeyValuePair<AutoResetEvent, ServerData> )args;
            AutoResetEvent ev = argPair.Key;
            ServerData serverData = argPair.Value;

            if( serverData.State == ServerState.ESTABLISHED )
            {
                if( serverData.PingInformation.PingReceived )
                {
                    serverData.PingInformation.NumberOfTries = 0;
                    serverData.PingInformation.PingReceived = false;
                }
                else
                {
                    if( serverData.PingInformation.NumberOfTries < ServerData.NUMBER_OF_PING_TRIES )
                        serverData.PingInformation.NumberOfTries += 1;
                    else
                    {
                        System.Console.WriteLine( String.Format( "I {0} suspect from the primary server {1}...", serverData.ServerId, serverData.ServersInformation.PrimaryId ) );
                        ev.Set( );
                    }
                }
            }
        }
    }
}